import { _decorator, Component, EventTouch, Label, Node, Sprite, tween, UIOpacity, UITransform, v2, v3, Vec2, Vec3 } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('SkillButton')
export class SkillButton extends Component {
    @property(Node) ndText: Node = null;
    @property(Node) ndIcon: Node = null;
    @property(Node) ndPanel: Node = null; // 面板

    private _isAvaliable: boolean = true; // 是否可用

    private _coldDownTime: number = 1; // 冷却时间 s

    private _isColding:boolean = false; // 是否在冷却中
    private _currColdTime: number = 0; // 当前冷却时间
    private _v2: Vec2 = v2();
    private _v3: Vec3 = v3();
    private _listener: Function;
    private _target: any;

    
    private _radian: number = 0;
    private _eventArg: [number, number] = [-1, -1];

    private _isPanelVisible: boolean = false;

    static readonly Event = {
        START: 0,
        MOVE: 1,
        END: 2,
        CANCEL: 3
    }



    public get coldDownTime(): number {
        return this._coldDownTime;
    }
    public set coldDownTime(value: number) {
        value = value >=0 ? value : 0;
        this._coldDownTime = value;
    }

    
    public get isAvaliable(): boolean {
        return this._isAvaliable;
    }
    public set isAvaliable(value: boolean) {
        this._isAvaliable = value;
        this.node.getComponentsInChildren(Sprite).forEach(sprite=> {
            sprite.grayscale = !value; // 设置灰度
        })
    }


    protected onEnable(): void {
        this.ndPanel.on(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.ndPanel.on(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.ndPanel.on(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.ndPanel.on(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
        this.ndText.active = false;
        this._hidePanel();
    }

    protected onDisable(): void {
        this.ndPanel.off(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.ndPanel.off(Node.EventType.TOUCH_MOVE, this.onTouchMove, this);
        this.ndPanel.off(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.ndPanel.off(Node.EventType.TOUCH_CANCEL, this.onTouchCancel, this);
    }


    start() {

    }

    update(deltaTime: number) {
        if(this._isColding) {
            this._currColdTime -= deltaTime;

            this.ndText.getComponent(Label).string = `${this._currColdTime.toFixed(1)}`; // 显示冷却时间

            if(this._currColdTime <= 0 ) {
                this._isColding = false;
                this.isAvaliable = true;
                this.ndText.active = false; // 隐藏冷却时间
            }
        }
    }

    private _showPanel() {
        if(this._isPanelVisible) return; // 如果面板已经显示，则不再显示
        this._isPanelVisible = true;
        const uiOpacity = this.ndPanel.getComponent(UIOpacity);

        tween(uiOpacity)
        .to(0.1, {
            opacity: 255
        },{
            easing: 'expoOut'
        })
        .start(); // 显示面板
    }

    private _hidePanel() {
        this._isPanelVisible = false;
        this.ndPanel.getComponent(UIOpacity).opacity = 0; // 显示面板
    }


    onEvent(listener: Function, target?: any) {
        this._listener = listener;
        this._target = target;
    }

    onTouchStart(event: EventTouch){
        // this.node.setScale(0.8, 0.8); // 按下时缩小
        // 技能在冷却不可使用
        if(this._isColding) return; // 如果在冷却中，则不响应事件

        this._eventArg[0] = SkillButton.Event.START;
        this._eventArg[1] = this._radian;
        this._listener && this._listener.apply(this._target, this._eventArg); // 触发事件
    }

    onTouchMove(event: EventTouch){
        if(this._isColding) return; // 如果在冷却中，则不响应事件
        event.getUILocation(this._v2); // 触摸点的世界坐标 world position
        this._v3.set(this._v2.x, this._v2.y); // world position

        const startWorldPos = this.node.worldPosition;
        const currWorldPos = this._v3; // world position
        const radian = Math.atan2(currWorldPos.y-startWorldPos.y, currWorldPos.x-startWorldPos.x);

        const distance = Vec2.distance(startWorldPos, currWorldPos);

        if(distance > 50) {
            this._showPanel();
            this._eventArg[0] = SkillButton.Event.MOVE;
            this._eventArg[1] = radian;
            this._radian = radian;
    
            this._listener && this._listener.apply(this._target, this._eventArg); // 触发事件
        } else {
            this._hidePanel(); // 隐藏面板
        }


    }

    onTouchEnd(){
        if(!this.isAvaliable) return;

        this._hidePanel();


        if(this._coldDownTime > 0) {
            this._currColdTime = this.coldDownTime;
            this._isColding = true; // 开始冷却
            this.isAvaliable = false;
            this.ndText.active = true;
            this.ndText.getComponent(Label).string = `${this._currColdTime.toFixed(1)}`; // 显示冷却时间
        } else {
            this._isColding = false; // 冷却结束
            this.isAvaliable = true;
            this.ndText.active = false;
        }


        this._eventArg[0] = SkillButton.Event.END;
        this._eventArg[1] = this._radian;
        this._listener && this._listener.apply(this._target, this._eventArg);
    }
    onTouchCancel(){
        // this.node.setScale(1, 1); // 松开时恢复原大小
        this._hidePanel();

        this._eventArg[0] = SkillButton.Event.CANCEL;
        this._eventArg[1] = this._radian;
        this._listener && this._listener.apply(this._target, this._eventArg);
    }
}


